#ifndef FACTORY_H
#define FACTORY_H

#include <map>
#include <string>
#include <functional>
#include "Singleton.h"

namespace Engine
{
	//to add to derived classes of game object's cpp file
	// T* createWatever() {return new T;}
	//static bool b = TheGameObjectFactory::Instance() ->AddType("name", createWatever);

	template <typename Key, typename Type>
	class Factory : public NonCopyable
	{
		public:
			typedef std::function<Type* (void)> Function;

		private:
			friend class Singleton <Factory>;
			Factory(){}
			typedef std::map <Key, Function> FactoryMap;
			FactoryMap m_factoryMap;

		public:
			Type* Create(const Key& type)
			{
				FactoryMap::iterator it = m_factoryMap.find(type);

				if(it != m_factoryMap.end())
				{
					return it ->second();
				}
				return nullptr;
			}

			bool AddType(const Key& type, Function f)
			{
				FactoryMap::iterator it = m_factoryMap.find(type);

				if(it != m_factoryMap.end())
				{
					return false;
				}

				m_factoryMap[type] = f;
				return true;
			}
	};
}

#endif

//
// -- Necther Louie Souribio
//
// -- Header -- Factory Class


#ifndef __FACTORY_H_
#define __FACTORY_H_

#include <map>
#include <string>
#include "Singleton.h"

template<class T>
class Factory : public Engine::NonCopyable
{
private:
	Factory(){}
	friend class Engine::Singleton<Factory>;

public:
	T* Create(const std::string& name)
	{
		Function f = m_map[name];
		if (f)
		{
			return f();
		}
		return 0;
	}

	typedef T* (*Function)();

	bool AddType(const std::string& name, Function f)
	{
		m_map[name] = f;
		return true;
	}

private:
	typedef std::map<std::string, Function> FactoryMap;
	FactoryMap m_map;
};


#endif